package forum;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;

public class User implements Serializable {

	private int userID;
	private int userlvl;
	private String name;
	private String email;
	private String password;
	private Timestamp joined;
	private int numberOfPosts;
	
	public User(int userID, int userlvl, String name, String email, String password, Timestamp joined, int numberOfPosts) {
		this.userID = userID;
		this.userlvl = userlvl;
		this.name = name;
		this.email = email;
		this.password = password;
		this.joined = joined;
		this.numberOfPosts = numberOfPosts;
	}
	
	public User(int userlvl, String name, String email, String password) {
		this.userID = 0;
		this.userlvl = userlvl;
		this.name = name;
		this.email = email;
		this.password = password;
		this.joined = new Timestamp(System.currentTimeMillis());
		this.numberOfPosts = 0;
	}
	
	public void Create(){
		Connection conn = db_code.connect();
		try {
			
			Statement stmt = conn.createStatement();
			String query = "INSERT INTO user (userlvl, name, email, password, joined, numberOfPosts)" +
					"VALUES(" + 
						userlvl + ",'" + 
						name + "','" + 
						email + "','" + 
						password + "','" + 
						joined + "'," + 
						numberOfPosts + ");";
			
			stmt.executeUpdate(query,Statement.RETURN_GENERATED_KEYS);
			ResultSet rs = stmt.getGeneratedKeys();
			
			if ( rs.next() ) {
			    int key = rs.getInt(1);
			    setUserID(key);
			}	
			db_code.disconnect(conn);
		} catch (Exception e) {
			db_code.disconnect(conn);
			System.out.println("FAIL! INSERT!");
			e.printStackTrace();
		}
	}
	
	public void Edit(){
		Connection conn = db_code.connect();
		try {
			
			Statement stmt = conn.createStatement();
			String query = "UPDATE user " +
					"SET " +
						"userlvl = " + userlvl + ","+
						"name = '" + name + "',"+
						"email = '" + email + "'"+
						"password = '" + password + "'"+
						"joined = '" + joined + "'"+
						"numberOfPosts = " + numberOfPosts +
					"WHERE " +
						"userID = " + userID;
			
			stmt.execute(query);
			db_code.disconnect(conn);
		} catch (Exception e) {
			db_code.disconnect(conn);
			System.out.println("FAIL! UPDATE!");
			e.printStackTrace();
		}
	}
	
	public void Delete(){
		Connection conn = db_code.connect();
		try {
			
			Statement stmt = conn.createStatement();
			String query = "DELETE FROM user WHERE userID = " + userID;
			
			stmt.execute(query);
			db_code.disconnect(conn);
		} catch (Exception e) {
			db_code.disconnect(conn);
			System.out.println("FAIL! DELETE!");
			e.printStackTrace();
		}
	}
	
	
	public synchronized void incrementNumberOfPosts(){
		Connection conn = db_code.connect();
		try{
			
			Statement stmt = conn.createStatement();
			String query = "UPDATE user SET numberOfPosts=numberOfPosts+1 WHERE userID = " + userID;
			stmt.execute(query);
			
			numberOfPosts++;
			
			db_code.disconnect(conn);
		}
		catch(SQLException e){
			db_code.disconnect(conn);
			System.out.println("SQL statement error!");
			e.printStackTrace();
		}
	}
	
	/**
	 * Fetches all the PMs that are send to the user with userId
	 * @return a Arraylist<PM> object, that can be null i think...
	 */
	public ArrayList<PM> getAllPMsToUser(){
		return getAllPMs(userID,true);
	} 
	
	/**
	 * Fetches all the PMs that the user with userID have sent.
	 * @return a Arraylist<PM> object, that can be null i think...
	 */
	public ArrayList<PM> getAllPMsSentByUser(){
		return getAllPMs(userID,false);
	} 
	
	/**
	 * @param userId - the UserID of the user
	 * @param ToTheUser - true if we are fetching PMS TO the user, false if we are fetching PMS FROM the user.
	 */
	private synchronized ArrayList<PM> getAllPMs(int userId, boolean ToTheUser){
		
		ArrayList<PM> result = new ArrayList<PM>();
		Connection conn = db_code.connect();
		try{
			
			Statement stmt = conn.createStatement();
			ResultSet rs = null;
			
			String query;
			
			if(ToTheUser)
				query = "SELECT * FROM pm WHERE toUserID = " + userId;
			else
				query = "SELECT * FROM pm WHERE fromUserID = " + userId;
			
			
			rs = stmt.executeQuery(query);
			PM row;
			while(rs.next()){
				row  = new PM(
						(Integer)rs.getObject("pmID"),
						(Integer)rs.getObject("fromUserID"), 
						(Integer)rs.getObject("toUserID"), 
						(Timestamp)rs.getObject("date"), 
						(String)rs.getObject("message"));
				result.add(row);
			}
			db_code.disconnect(conn);
			return result;
		}
		catch(SQLException e){
			db_code.disconnect(conn);
			System.out.println("SQL statement error!");
			e.printStackTrace();
		}
		return null;
	} 
	
	public ArrayList<Thread> getAllThreadsByUser(){

		ArrayList<Thread> result = new ArrayList<Thread>();
		Connection conn =  db_code.connect();
		try{
			
			
			Statement stmt =conn.createStatement();
			System.out.println("created Statement");
			ResultSet rs = null;
			
			String query = "SELECT * FROM thread WHERE createdBy = " + userID;

			rs = stmt.executeQuery(query);
			System.out.println("Executed Query!");
			Thread row;
			while(rs.next()){
				row  = new Thread(
						(Integer)rs.getObject("threadID"), 
						(Integer)rs.getObject("subForumID"), 
						(String)rs.getObject("name"), 
						(Integer)rs.getObject("createdBy"), 
						(Timestamp)rs.getObject("createdOn"), 
						(Integer)rs.getObject("views"), 
						(Integer)rs.getObject("replies"));
				result.add(row);
			}
			db_code.disconnect(conn);
			System.out.println("Found " + result.size() + " threads!");
			return result;
		}
		catch(SQLException e){
			db_code.disconnect(conn);
			System.out.println("SQL statement error!");
			e.printStackTrace();
		}
		return null;
	}
	
	private ArrayList<Post> getAllPostsByUser(){
		ArrayList<Post> result = new ArrayList<Post>();
		Connection conn =  db_code.connect();
		try{
			
			Statement stmt =conn.createStatement();
			ResultSet rs = null;
			
			String query = "SELECT * FROM post WHERE userID = " + userID;

			rs = stmt.executeQuery(query);
			
			Post row;
			while(rs.next()){
				row  = new Post(
						(Integer)rs.getObject("postID"), 
						(Integer)rs.getObject("threadID"), 
						(Integer)rs.getObject("userID"), 
						(String)rs.getObject("content"), 
						(Timestamp)rs.getObject("createdOn"), 
						(Timestamp)rs.getObject("lasteditedOn"));
				result.add(row);
			}
			db_code.disconnect(conn);
			return result;
		}
		catch(SQLException e){
			db_code.disconnect(conn);
			System.out.println("SQL statement error!");
			e.printStackTrace();
		}
		return null;
	}
	
	public String toString(){
		return "User:"+getName() + ", " + getEmail() + ", " + getUserID();
	}
	
	public int getUserID() {
		return userID;
	}

	public void setUserID(int userID) {
		this.userID = userID;
	}

	public int getUserlvl() {
		return userlvl;
	}

	public void setUserlvl(int userlvl) {
		this.userlvl = userlvl;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getJoined() {
		return joined;
	}

	public void setJoined(Timestamp joined) {
		this.joined = joined;
	}

	public int getNumberOfPosts() {
		return numberOfPosts;
	}

	public void setNumberOfPosts(int numberOfPosts) {
		this.numberOfPosts = numberOfPosts;
	}
}
